#pragma once

#include <windows.h>
#include "Log.h"
#include "KeyEventArgs.h"
#include "ScriptBase.h"

using namespace System;
using namespace System::Reflection;

namespace GTA
{
	namespace Events
	{
		public ref class KeyDown
		{
		private:
			static Object^ Sender;
			static KeyEventArgs^ Args;
		public:
			static event EventHandler<KeyEventArgs^>^ Handler;
			static void Invoke(Object^ sender, KeyEventArgs^ args)
			{
				Sender = sender;
				Args = args;
			}
			static void Call()
			{
				if (Args == nullptr) return;
				Handler(Sender,Args);
				Args = nullptr;
			}
		};

		public ref class KeyUp
		{
		private:
			static Object^ Sender;
			static KeyEventArgs^ Args;
		public:
			static event EventHandler<KeyEventArgs^>^ Handler;
			static void Invoke(Object^ sender, KeyEventArgs^ args)
			{
				Sender = sender;
				Args = args;
			}
			static void Call()
			{
				if (Args == nullptr) return;
				Handler(Sender,Args);
				Args = nullptr;
			}
		};

		public ref class OnStart
		{
		private:
			static Object^ Sender;
			static EventArgs^ Args;
		public:
			static event EventHandler<EventArgs^>^ Handler;
			static void Invoke(Object^ sender, EventArgs^ args)
			{
				Sender = sender;
				Args = args;
			}
			static void Call()
			{
				if (Args == nullptr) return;
				Handler(Sender,Args);
				Args = nullptr;
			}
		};

		public ref class RunTick
		{
		private:
			static Object^ Sender;
			static EventArgs^ Args;
		public:
			static event EventHandler<EventArgs^>^ Handler;
			static void Invoke(Object^ sender, EventArgs^ args)
			{
				Sender = sender;
				Args = args;
			}
			static void Call()
			{
				if (Args == nullptr) return;
				Handler(Sender,Args);
				Args = nullptr;
			}
		};

		
		public ref class CleanUpEventArgs : EventArgs
		{
		private:

		public:
			GTA::ScriptBase^ Script;

			CleanUpEventArgs(GTA::ScriptBase^ script)
			{
				Script = script;
			}
		};


		public ref class CleanUp
		{
		private:
			static Object^ Sender;
			static CleanUpEventArgs^ Args;
		public:
			static event EventHandler<CleanUpEventArgs^>^ Handler;
			static void Invoke(Object^ sender, CleanUpEventArgs^ args)
			{
				Sender = sender;
				Args = args;
			}
			static void Call()
			{
				if (Args == nullptr) return;
				Handler(Sender,Args);
				Args = nullptr;
			}
		};


		public ref class DomainUnload
		{ // this event will be called by system thread
		private:
			static Object^ Sender;
			static EventArgs^ Args;
		public:
			static event EventHandler<EventArgs^>^ Handler;
			static void Invoke(Object^ sender, EventArgs^ args)
			{
				Sender = sender;
				Args = args;
			}
			static void Call()
			{
				if (Args == nullptr) return;
				Handler(Sender,Args);
				Args = nullptr;
			}
		};
	};
};